# -*- coding: utf-8 -*-

"""
This implements the OpenGL widget
"""
import copy
        
from PyQt4 import QtOpenGL
from OpenGL import GL

from mathematic import Vector

from convexhull import ConvexHull

class Drawer(object):
    """
        This class is responsible by draw all elements how: curve and points.
    """
    
    
    def __init__ (self, convexhull):
        """
            The atribute curve is a composition. This object contain attibutes 
            and methods to draw a curve.
        """
        self.point_size = 5
        
        self.density = 1
        
        # Colors
        self.points_color = [1.0, 0.0, 0.0]
        self.edges_color = [0.0, 1.0, 0.0]
        
        self.convexhull = convexhull
        
        self.point1 = self.point2 = Vector( [0.0, 0.0] )

    def setPointsColor(self, r, g, b):
        self.points_color[0] = r
        self.points_color[1] = g
        self.points_color[2] = b

    def setEdgesColor(self, r, g, b):
        self.edges_color[0] = r
        self.edges_color[1] = g
        self.edges_color[2] = b

    def setPointSize(self, size):
        self.point_size = size
        
    def drawLine(self, point1, point2):
        """
            Drawer a line that contain the points of attribute point1 and point2.
            
            The color of curve is determined by combination of colors 
            represented by parameters r (red), g (green) and b (blue).
        """
        
        GL.glColor3f(self.edges_color[0], self.edges_color[1], self.edges_color[2])
        GL.glBegin(GL.GL_LINES)
        GL.glVertex2fv(point1)
        GL.glVertex2fv(point2)
        GL.glEnd()


    def drawPoint(self, point):
        """
            Drawer the point of the attribute point1.
            
            The color of curve is determined by combination of colors 
            represented by parameters r (red), g (green) and b (blue).
        """
        GL.glColor3f(self.points_color[0], self.points_color[1], self.points_color[2])
        GL.glPointSize(self.point_size)
        GL.glBegin(GL.GL_POINTS)
        GL.glVertex2fv(point)
        GL.glEnd()
        
    def drawPoints(self):
        """
            Drawer a set of the points contained in attribute point_list.
            
            The color of curve is determined by combination of colors 
            represented by parameters r (red), g (green) and b (blue).
        """
        for i in range( len(self.convexhull.points) ):
	        self.drawPoint(self.convexhull.points[i])
	        
    def drawConvexHull(self):
        lenght = len(self.convexhull.edges)
        for i in range(lenght):
	        self.drawLine(self.convexhull.edges[i],self.convexhull.edges[(i+1)%lenght])
	        
    
class GlWidget (QtOpenGL.QGLWidget):
    """
        A simple OpenGL pane
    """
    
    def __init__ (self, parent=None):
        """
            TODO
        """
        super (GlWidget, self).__init__(parent)
        
        self.window_left = None
        self.window_top = None
        self.window_right = None
        self.window_bottom = None

        self.viewport_left = None
        self.viewport_top = None
        self.viewport_width = None
        self.viewport_height = None

        self.back_red = 1.0
        self.back_green = 1.0
        self.back_blue = 1.0
        self.back_alpha = 0.0                        
        
        self.show = False
        
        self.drawer = Drawer(self.parent().parent().parent().convexhull)

    def setBackgroundColor(self, r, g, b, a=0.0):
        self.back_red = r
        self.back_green = g
        self.back_blue = b
        self.back_alpha = a 
        
    def paintGL(self):
        """
            This method is responsible to Draw in GLWidget.
            
            This is called automatically when the widget is created. After 
            this is called virtually by method glDraw.
            
            The painter is modified according the FactoryPainter. So in 
            different moment this method can have a different behavior
        """

        GL.glClearColor(self.back_red, self.back_green, self.back_blue, self.back_alpha)
        GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)


        if self.show:
            self.drawer.drawConvexHull()
            
        self.drawer.drawPoints()
        
        GL.glFlush()
     
    def resizeGL (self, width, height):
        """
            This method calculate the coordinates of window
        """
        self.viewport_left = 0
        self.viewport_top = 0
        self.viewport_width = width
        self.viewport_height = height

        # Mudar
        x0 = -5.0
        x1 = 5.0
        y0 = 5.0
        y1 = -5.0

        if (x1 - x0) <= (y1 - y0):
            self.window_left = x0 * ((x1 - x0) / (y0 - y1)) * (height / width)
            self.window_right = x1 * ((x1 - x0) / (y0 - y1)) * (height / width)
            self.window_bottom = y1 * height / width
            self.window_top = y0 * height / width
        else:
            self.window_left = x0 * ((y0 - y1) / (x1 - x0)) * (width / height)
            self.window_right = x1 * ((y0 - y1) / (x1 - x0)) * (width / height)
            self.window_bottom = y1
            self.window_top = y0
        
        GL.glViewport( self.viewport_left,  self.viewport_top, 
                       self.viewport_width, self.viewport_height)
        
        GL.glMatrixMode(GL.GL_PROJECTION)
        GL.glLoadIdentity()

        GL.glOrtho( self.window_left,   self.window_right, 
                    self.window_bottom, self.window_top, -5.0, 5.0)

        GL.glMatrixMode(GL.GL_MODELVIEW)
        GL.glLoadIdentity()
        self.glDraw()

    def mousePressEvent(self, event):
        horizontal = self.window_right - self.window_left
        vertical = self.window_bottom - self.window_top
        point = Vector( 
                 [(event.x()*horizontal/self.viewport_width)-(horizontal/2.0),
                  (event.y()*vertical/self.viewport_height)-(vertical/2.0)])
        
        mainwindow = self.parent().parent().parent()
        mainwindow.browser.append(str(point))            

        r = float( mainwindow.pointsColor.red()   ) / 255
        g = float( mainwindow.pointsColor.green() ) / 255 
        b = float( mainwindow.pointsColor.blue()  ) / 255
        self.drawer.setPointsColor(r, g, b)

        self.drawer.convexhull.points.append(point)
        
        self.glDraw()
